package com.shareware.common.utils

import android.util.Base64
import java.io.ByteArrayOutputStream
import java.math.BigDecimal
import java.security.MessageDigest
import java.text.DecimalFormat
import java.util.zip.GZIPOutputStream

/**
 * desc: 功能描述
 * email: mobiledeveloper@qq.com
 */

/**
 * 判断是否为一个合法的phone num
 *
 * @return true or false
 */
fun String.checkPhone(): Boolean {
    return Regex("[1][3456789]\\d{9}").matches(this)
}

fun Byte.toHexString(): String {
    return Integer.toHexString(this.toInt() and 0xff or 0x100).substring(1).uppercase()
}

fun String.base64ToBytes(): ByteArray {
    return Base64.decode(this, Base64.DEFAULT)
}

/**
 * Converts hex values from strings to byte array
 *
 * @return decoded byte array
 */
fun String.hexToByteArray(): ByteArray {
    val len = this.length
    val data = ByteArray(len / 2)
    var i = 0
    while (i < len) {
        data[i / 2] = ((Character.digit(this[i], 16) shl 4) + Character
            .digit(this[i + 1], 16)).toByte()
        i += 2
    }
    return data
}

fun ByteArray.toHexString(): String {
    val hexDigits =
        charArrayOf('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f')
    val size = this.size
    val res = CharArray(size shl 1)
    var i = 0
    var j = 0
    while (i < size) {
        res[j++] = hexDigits[this[i].toInt().ushr(4) and 0x0f]
        res[j++] = hexDigits[this[i].toInt() and 0x0f]
        i++
    }
    return String(res)
}


/**
 * 生成的MD5值
 * @return MD5值
 */
fun String.encodeMd5(): String {
    val mdTemp = MessageDigest.getInstance("Md5")
    mdTemp.update(this.toByteArray(charset("UTF-8")))
    return mdTemp.digest().toHexString()
}

fun ByteArray.encodeMd5(): String {
    val mdTemp = MessageDigest.getInstance("Md5")
    mdTemp.update(this)
    return mdTemp.digest().toHexString()
}

/**
 * 判断当前字符是否为英文
 *
 * @return boolean
 */
fun Char.isLetter(): Boolean {
    return this in 'A'..'Z' || this in 'a'..'z'
}

fun Char.nextLine(): Boolean {
    return '\n' == this || '\r' == this
}

fun Double.decimalTwo(): String {
    return DecimalFormat("0.00").format(this)
}

/**
 * 判断一个url是否为图片url
 *
 * @return true or false
 */

fun String.checkImageUrl(): Boolean {
    return Regex(".*?(gif|jpeg|png|jpg|bmp)").matches(this)
}

/**
 * 判断是否为一个合法的url地址
 *
 * @return true or false
 */

fun String.checkUrl(): Boolean {
    return Regex("^(https|http)://.*?$(net|com|.com.cn|org|me|)").matches(this)
}

fun String.checkHttpUrl(): Boolean {
    return Regex("^(https|http)://.*").matches(this)
}

/**
 * String gzip压缩
 */
fun String.gzipCompress(): ByteArray {
    ByteArrayOutputStream().use { out ->
        GZIPOutputStream(out).use { gzip ->
            gzip.write(this.toByteArray())
        }
        return out.toByteArray()
    }
}

/**
 * byte array gzip压缩
 */
fun ByteArray.gzipCompress(): ByteArray {
    ByteArrayOutputStream().use { out ->
        GZIPOutputStream(out).use { gzip ->
            gzip.write(this)
        }
        return out.toByteArray()
    }
}

/**
 * 保留指定小数位，四舍五入，返回double类型
 * @param scale 小数位数
 */
fun Double.format(scale: Int): Double {
    return BigDecimal(this).setScale(scale, BigDecimal.ROUND_HALF_UP).toDouble()
}

/**
 * 比较版本号字符串大小
 * >0
 * =0
 * <0
 */
fun String.compareToVersion(version: String): Int? {
    val target = version.split(".").filter { it.isNotEmpty() }
    val current = this.split(".").filter { it.isNotEmpty() }
    val size = if (current.size > target.size) {
        target.size
    } else {
        current.size
    }
    var index = 0
    val regex = Regex("^\\d+")
    while (index < size) {
        val currentValue = regex.find(current[index])?.value?.toInt() ?: return null
        val targetValue = regex.find(target[index])?.value?.toInt() ?: return null
        index++
        if (currentValue == targetValue) {
            continue
        }
        return if (currentValue > targetValue) {
            1
        } else {
            -1
        }
    }
    return if (current.size > target.size) {
        1
    } else if (current.size < target.size) {
        -1
    } else {
        0
    }
}